﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Web;
using System.Collections;
using System.Linq;
using Microsoft.SharePoint.Linq;
using System.Collections.Generic;

namespace KWSResourceBooking.KWSResourceCalendar
{
    public partial class KWSResourceCalendarUserControl : UserControl
    {
        public KWSResourceCalendar WebPart { get; set; }
    }

    public partial class KWSResourceCalendarUserControl : UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {                
                SPList list = SPContext.Current.Web.Lists.TryGetList(this.WebPart.ResourceListTitle);
                if (list != null)
                {                    
                    cblResources.DataSource = list.Items.GetDataTable();
                    cblResources.DataBind();
                    ddlResource.DataSource = list.Items.GetDataTable();
                    ddlResource.DataTextField = "Title";
                    ddlResource.DataValueField = "ID";
                    ddlResource.DataBind();
                    lblResources.Visible = false;
                }
                else
                {
                    cblResources.Visible = false;
                    lblResources.Visible = true;
                }

                List<string> resources = (from item in cblResources.Items.Cast<ListItem>()
                                          select item.Text).ToList();
   
                DateTime firstDayOfWeek = DateTime.Now.AddDays(-(int)DateTime.Now.DayOfWeek + 1);
                RenderWeek(firstDayOfWeek, resources);
                hidWeekStartDate.Value = firstDayOfWeek.ToString();
            }
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            ScriptManager.RegisterClientScriptInclude(this, typeof(Page), "entityeditor", "/_layouts/entityeditor.js");
            ScriptManager.RegisterClientScriptInclude(this, typeof(Page), "datepicker", "/_layouts/datepicker.js");
            dtcFrom.LocaleId = (int)SPContext.Current.RegionalSettings.LocaleId;
            dtcTo.LocaleId = (int)SPContext.Current.RegionalSettings.LocaleId;
        }

        protected void btnDay_Click(object sender, EventArgs e)
        {
            pnlCalendar.Visible = false;
            pnlBooking.Visible = true;
            ImageButton btnDay = (ImageButton)sender;
            DateTime day = DateTime.Parse(btnDay.CommandArgument);
            TimeSpan timeSpan = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            day = day.Date + timeSpan;
            ddlResource.SelectedIndex = 0;
            dtcFrom.SelectedDate = day.AddMinutes(15 - day.Minute % 15);
            dtcTo.SelectedDate = day.AddMinutes(15 - day.Minute % 15).AddHours(1);
            speOwner.CommaSeparatedAccounts = SPContext.Current.Web.CurrentUser.LoginName;
            speOwner.Validate();
        }

        private void RenderWeek(DateTime weekStartDate, List<string> filter)
        {
            lblWeek.Text = weekStartDate.ToShortDateString() + " to " + weekStartDate.AddDays(6).ToShortDateString();

            RenderDay(1, weekStartDate, filter);
            RenderDay(2, weekStartDate.AddDays(1), filter);
            RenderDay(3, weekStartDate.AddDays(2), filter);
            RenderDay(4, weekStartDate.AddDays(3), filter);
            RenderDay(5, weekStartDate.AddDays(4), filter);
            RenderDay(6, weekStartDate.AddDays(5), filter);
            RenderDay(7, weekStartDate.AddDays(6), filter);
        }

        private void RenderDay(int dayNumber, DateTime day, List<string> filter)
        {
            if (filter.Count == 0)
                filter = cblResources.Items.Cast<ListItem>().Select(n => n.Text).ToList();            

            Label lblDay = (Label)FindControl("lblDay" + dayNumber.ToString());
            lblDay.Text = day.DayOfWeek + " " + day.ToString("d MMMM yyyy");
            ImageButton btnDay = (ImageButton)FindControl("btnDay" + dayNumber.ToString());
            btnDay.CommandArgument = day.ToString();
            SPList listBookings = SPContext.Current.Web.Lists.TryGetList(this.WebPart.ResourceBookingListTitle);
            if (listBookings != null)
            {
                using (DataContext data = new DataContext(SPContext.Current.Web.Url))
                {
                    EntityList<KWSBookingsItem> Bookings = data.GetList<KWSBookingsItem>(this.WebPart.ResourceBookingListTitle);
                    var todaysBookings = from booking in Bookings
                                         where booking.From.Value.Date == day.Date
                                         && filter.Contains(booking.Title)
                                         orderby booking.From ascending
                                         select booking;
                    Repeater repeater = (Repeater)FindControl("repDay" + dayNumber.ToString());
                    repeater.DataSource = todaysBookings;
                    repeater.DataBind();
                }
            }
        }

        protected void repDay_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                KWSBookingsItem item = (KWSBookingsItem)e.Item.DataItem;
                if (item.OwnerId.Value == SPContext.Current.Web.CurrentUser.ID  && item.From > DateTime.Now)
                    e.Item.FindControl("btnDelete").Visible = true;
                else
                    ((Label)e.Item.FindControl("lblFrom")).Style.Add("margin-left","25px");
            }
        }

        protected void btnDelete_Click(object sender, EventArgs e)
        {
            ImageButton btnDelete = (ImageButton)sender;    
            SPList list = SPContext.Current.Web.Lists.TryGetList(this.WebPart.ResourceBookingListTitle);
            if (list != null)
            {
                list.Items.DeleteItemById(Int32.Parse(btnDelete.CommandArgument));
                DateTime firstDayOfWeek = DateTime.Parse(hidWeekStartDate.Value);
                RenderWeek(firstDayOfWeek, cblResources.Items.Cast<ListItem>().Where(n => n.Selected).Select(n => n.Text).ToList());
            }
        }

        protected void btnWeek_Click(object sender, EventArgs e)
        {
            DateTime firstDayOfWeek = DateTime.Parse(hidWeekStartDate.Value);
            if (((ImageButton)sender).CommandArgument.ToString().ToLower() == "next")
                firstDayOfWeek = firstDayOfWeek.AddDays(7);
            else
                firstDayOfWeek = firstDayOfWeek.AddDays(-7);
            hidWeekStartDate.Value = firstDayOfWeek.ToString();
            RenderWeek(firstDayOfWeek, cblResources.Items.Cast<ListItem>().Where(n => n.Selected).Select(n => n.Text).ToList());
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (Page.IsValid)
            {
                SPList list = SPContext.Current.Web.Lists.TryGetList(this.WebPart.ResourceBookingListTitle);
                if (list != null)
                {
                    SPListItem item = list.Items.Add();
                    item["Title"] = ddlResource.SelectedItem.Text;
                    item["KWSBookingOwner"] = SPContext.Current.Web.EnsureUser(((Microsoft.SharePoint.WebControls.PickerEntity)speOwner.ResolvedEntities[0]).Key);
                    item["KWSBookingFrom"] = dtcFrom.SelectedDate;
                    item["KWSBookingTo"] = dtcTo.SelectedDate;
                    item["KWSBookingSummary"] = txtSummary.Text;
                    item.Update();

                    DateTime firstDayOfWeek = DateTime.Parse(hidWeekStartDate.Value);
                    RenderWeek(firstDayOfWeek, cblResources.Items.Cast<ListItem>().Where(n => n.Selected).Select(n => n.Text).ToList());
                }

                pnlBooking.Visible = false;
                pnlCalendar.Visible = true;
            }
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            pnlBooking.Visible = false;
            pnlCalendar.Visible = true;
        }

        protected void cvFromBeforeTo_ServerValidate(object sender, ServerValidateEventArgs e)
        {
            if (dtcTo.SelectedDate < dtcFrom.SelectedDate) e.IsValid = false;
        }

        protected void cvDoubleBooking_ServerValidate(object sender, ServerValidateEventArgs e)
        {
            using (DataContext data = new DataContext(SPContext.Current.Web.Url))
            {
                EntityList<KWSBookingsItem> Bookings = data.GetList<KWSBookingsItem>(this.WebPart.ResourceBookingListTitle);
                var doubleBookings = from booking in Bookings
                                     where booking.Title == ddlResource.SelectedItem.Text
                                     && ((dtcFrom.SelectedDate.Ticks <= booking.From.Value.Ticks & dtcTo.SelectedDate.Ticks >= booking.To.Value.Ticks) ||
                                     (dtcFrom.SelectedDate.Ticks >= booking.From.Value.Ticks & dtcFrom.SelectedDate.Ticks <= booking.To.Value.Ticks & dtcTo.SelectedDate.Ticks >= booking.To.Value.Ticks) ||
                                     (dtcFrom.SelectedDate.Ticks <= booking.From.Value.Ticks & dtcTo.SelectedDate.Ticks >= booking.From.Value.Ticks & dtcTo.SelectedDate.Ticks <= booking.To.Value.Ticks) ||
                                     (dtcFrom.SelectedDate.Ticks == booking.From.Value.Ticks & dtcTo.SelectedDate.Ticks == booking.To.Value.Ticks) ||
                                     (dtcFrom.SelectedDate.Ticks >= booking.From.Value.Ticks & dtcTo.SelectedDate.Ticks <= booking.To.Value.Ticks))
                                     select booking;
               
                if (doubleBookings.Count() > 0)
                {
                    e.IsValid = false;
                    KWSBookingsItem item = doubleBookings.First();
                    cvResource.ErrorMessage = "This resource is already booked by " + item.Owner + " from " + item.From.Value.ToString("HH:mm") + " to " + item.To.Value.ToString("HH:mm") + ".";
                }
            }
        }

        protected void cblResources_SelectedIndexChanged(object sender, EventArgs e)
        {
            DateTime firstDayOfWeek = DateTime.Parse(hidWeekStartDate.Value);
            RenderWeek(firstDayOfWeek, cblResources.Items.Cast<ListItem>().Where(n => n.Selected).Select(n => n.Text).ToList());
        }
    }
}
